package org.migsoft.id3lib.id3v1;

import java.util.Arrays;

import org.migsoft.id3lib.ID3Exception;
import org.migsoft.id3lib.StringDecoder;
import org.migsoft.id3lib.stringdecoders.UTF8Decoder;

public class ID3v1Tag {
  private byte[] myBytes;
  private StringDecoder decoder;
  
  public static boolean isValidID3v1Tag(byte[] data) {
    if(data.length < 128)
      return false;
    if(data[data.length - 128] != 'T' || data[data.length - 127] != 'A' || data[data.length - 126] != 'G')
      return false;
    return true;
  }
  
  public ID3v1Tag(byte[] myBytes, StringDecoder decoder) throws ID3Exception{
    super();
    if(!isValidID3v1Tag(myBytes) || myBytes.length != 128)
      throw new ID3Exception("Invalid id3v1 data");
    this.myBytes = myBytes;
    this.decoder = decoder;
  }

  private ID3v1Tag() throws ID3Exception{
    this.myBytes = new byte[128];
    myBytes[0] = 'T';
    myBytes[1] = 'A';
    myBytes[2] = 'G';
    this.decoder = new UTF8Decoder();
  }
  
  public ID3v1Tag(ID3v1Tag id3v1Tag) {
    myBytes = new byte[id3v1Tag.myBytes.length];
    System.arraycopy(id3v1Tag.myBytes, 0, myBytes, 0, myBytes.length);
    decoder = id3v1Tag.decoder;
  }

  public String getTitle(){
    return decoder.decode(getBytes(3, 30));
  }
  
  public String getArtist(){
    return decoder.decode(getBytes(33, 30));
  }
  
  public String getAlbum(){
    return decoder.decode(getBytes(63, 30));
  }

  public String getYear(){
    return decoder.decode(getBytes(93, 4));
  }
  public String getComment(){
    return decoder.decode(getBytes(97, 30));
    
  }
  public Genre getGenre(){
    return Genre.GENRES[myBytes[127] & 0xFF];
  }
  
  public void setTitle(String value) throws ID3Exception {
    setBytes(3, 30, value.getBytes());
  }

  public void setArtist(String value) throws ID3Exception {
    setBytes(33, 30, value.getBytes());
  }

  public void setAlbum(String value) throws ID3Exception {
    setBytes(63, 30, value.getBytes());
  }

  public void setYear(String value) throws ID3Exception {
    setBytes(93, 4, value.getBytes());
  }

  public void setComment(String value) throws ID3Exception {
    setBytes(97, 30, value.getBytes());
  }

  public void setGenre(Genre value) throws ID3Exception {
    myBytes[127] = value.getCode();
  }

  private void setBytes(int offset, int size, byte[] bytes) throws ID3Exception {
    if(bytes.length > size)
      throw new ID3Exception("Parameter value is too long(max is " + size + " bytes)");
    Arrays.fill(myBytes, offset, offset + size, (byte)0);
    System.arraycopy(bytes, 0, myBytes, offset, bytes.length);
  }

  private byte[] getBytes(int start, int size) {
    int zeroIndex = 0;
    for(int i = 0; i <  size; i++){
      zeroIndex = i;
      if(myBytes[start + i] == 0) 
        break;
      zeroIndex ++;
    }
    byte[] ret = new byte[zeroIndex];
    System.arraycopy(myBytes, start, ret, 0, zeroIndex);
    return ret;
  }
  
  public byte[] getBytes(){
    return myBytes;
  }

}
